// ==================== 图纸导入服务 ====================
// 应用层服务模块
// 职责：处理图纸文件的导入、解析和渲染

/**
 * 图纸导入服务类
 * 负责处理各种格式的图纸文件导入和解析
 */
export class DrawingImportService {
  /**
   * 构造函数
   * @param {Object} options - 配置选项
   */
  constructor(options = {}) {
    // ==================== 支持的文件格式 ====================
    this.supportedFormats = {
      // 图片格式
      image: {
        extensions: ['.jpg', '.jpeg', '.png', '.gif', '.bmp', '.webp', '.svg'],
        mimeTypes: ['image/jpeg', 'image/png', 'image/gif', 'image/bmp', 'image/webp', 'image/svg+xml'],
        handler: this.handleImageFile.bind(this)
      },
      // PDF格式
      pdf: {
        extensions: ['.pdf'],
        mimeTypes: ['application/pdf'],
        handler: this.handlePDFFile.bind(this)
      },
      // CAD格式（简化处理）
      cad: {
        extensions: ['.dwg', '.dxf'],
        mimeTypes: ['application/dwg', 'application/dxf'],
        handler: this.handleCADFile.bind(this)
      }
    }
    
    // ==================== 配置选项 ====================
    this.options = {
      maxFileSize: 50 * 1024 * 1024, // 50MB
      allowedFormats: Object.keys(this.supportedFormats),
      autoScale: true,                // 自动缩放
      maintainAspectRatio: true,      // 保持宽高比
      ...options
    }
    
    // ==================== 导入状态 ====================
    this.importState = {
      isImporting: false,
      currentFile: null,
      progress: 0,
      error: null
    }
    
    // ==================== 图纸数据 ====================
    this.drawingData = {
      layers: [],           // 图纸图层
      objects: [],          // 图纸对象
      metadata: {},         // 图纸元数据
      bounds: null          // 图纸边界
    }
  }
  
  // ==================== 文件选择器 ====================
  
  /**
   * 打开文件选择器
   * @param {Object} options - 选择器选项
   * @returns {Promise<File>} 选择的文件
   */
  async openFileSelector(options = {}) {
    return new Promise((resolve, reject) => {
      // 创建文件输入元素
      const input = document.createElement('input')
      input.type = 'file'
      input.accept = this.getAcceptString()
      input.multiple = options.multiple || false
      
      // 设置文件大小限制
      if (this.options.maxFileSize) {
        input.addEventListener('change', (event) => {
          const files = Array.from(event.target.files)
          const oversizedFiles = files.filter(file => file.size > this.options.maxFileSize)
          
          if (oversizedFiles.length > 0) {
            reject(new Error(`文件大小超过限制 (${this.options.maxFileSize / 1024 / 1024}MB)`))
            return
          }
          
          resolve(options.multiple ? files : files[0])
        })
      } else {
        input.addEventListener('change', (event) => {
          resolve(options.multiple ? Array.from(event.target.files) : event.target.files[0])
        })
      }
      
      // 处理取消选择
      input.addEventListener('cancel', () => {
        reject(new Error('用户取消选择文件'))
      })
      
      // 触发文件选择
      input.click()
    })
  }
  
  /**
   * 获取接受的文件类型字符串
   * @returns {string} MIME类型字符串
   */
  getAcceptString() {
    const types = []
    
    for (const format of this.options.allowedFormats) {
      if (this.supportedFormats[format]) {
        types.push(...this.supportedFormats[format].mimeTypes)
      }
    }
    
    return types.join(',')
  }
  
  // ==================== 文件处理 ====================
  
  /**
   * 导入图纸文件
   * @param {File} file - 图纸文件
   * @returns {Promise<Object>} 导入结果
   */
  async importDrawing(file) {
    try {
      this.importState.isImporting = true
      this.importState.currentFile = file
      this.importState.progress = 0
      this.importState.error = null
      
      // 验证文件格式
      const format = this.detectFileFormat(file)
      if (!format) {
        throw new Error(`不支持的文件格式: ${file.name}`)
      }
      
      // 验证文件大小
      if (file.size > this.options.maxFileSize) {
        throw new Error(`文件大小超过限制: ${(file.size / 1024 / 1024).toFixed(2)}MB`)
      }
      
      // 处理文件
      this.importState.progress = 20
      const result = await this.supportedFormats[format].handler(file)
      
      this.importState.progress = 80
      
      // 处理图纸数据
      const drawingData = await this.processDrawingData(result, file)
      
      this.importState.progress = 100
      this.importState.isImporting = false
      
      return {
        success: true,
        data: drawingData,
        file: file,
        format: format
      }
      
    } catch (error) {
      this.importState.error = error.message
      this.importState.isImporting = false
      
      return {
        success: false,
        error: error.message,
        file: file
      }
    }
  }
  
  /**
   * 检测文件格式
   * @param {File} file - 文件对象
   * @returns {string|null} 文件格式
   */
  detectFileFormat(file) {
    const fileName = file.name.toLowerCase()
    const mimeType = file.type.toLowerCase()
    
    for (const [format, config] of Object.entries(this.supportedFormats)) {
      // 检查文件扩展名
      const hasValidExtension = config.extensions.some(ext => 
        fileName.endsWith(ext.toLowerCase())
      )
      
      // 检查MIME类型
      const hasValidMimeType = config.mimeTypes.some(type => 
        mimeType.includes(type.toLowerCase())
      )
      
      if (hasValidExtension || hasValidMimeType) {
        return format
      }
    }
    
    return null
  }
  
  // ==================== 格式处理器 ====================
  
  /**
   * 处理图片文件
   * @param {File} file - 图片文件
   * @returns {Promise<Object>} 处理结果
   */
  async handleImageFile(file) {
    return new Promise((resolve, reject) => {
      const reader = new FileReader()
      
      reader.onload = (event) => {
        const img = new Image()
        
        img.onload = () => {
          resolve({
            type: 'image',
            data: event.target.result,
            image: img,
            width: img.width,
            height: img.height,
            aspectRatio: img.width / img.height
          })
        }
        
        img.onerror = () => {
          reject(new Error('图片加载失败'))
        }
        
        img.src = event.target.result
      }
      
      reader.onerror = () => {
        reject(new Error('文件读取失败'))
      }
      
      reader.readAsDataURL(file)
    })
  }
  
  /**
   * 处理PDF文件
   * @param {File} file - PDF文件
   * @returns {Promise<Object>} 处理结果
   */
  async handlePDFFile(file) {
    // 注意：这里需要PDF.js库支持
    // 简化实现，实际项目中需要集成PDF.js
    return new Promise((resolve, reject) => {
      // 检查是否支持PDF处理
      if (typeof window.pdfjsLib === 'undefined') {
        reject(new Error('PDF处理库未加载，请先引入PDF.js'))
        return
      }
      
      const reader = new FileReader()
      
      reader.onload = async (event) => {
        try {
          const arrayBuffer = event.target.result
          const pdf = await window.pdfjsLib.getDocument(arrayBuffer).promise
          const page = await pdf.getPage(1) // 获取第一页
          
          const viewport = page.getViewport({ scale: 1.0 })
          
          resolve({
            type: 'pdf',
            data: arrayBuffer,
            pdf: pdf,
            page: page,
            width: viewport.width,
            height: viewport.height,
            aspectRatio: viewport.width / viewport.height
          })
        } catch (error) {
          reject(new Error(`PDF处理失败: ${error.message}`))
        }
      }
      
      reader.onerror = () => {
        reject(new Error('PDF文件读取失败'))
      }
      
      reader.readAsArrayBuffer(file)
    })
  }
  
  /**
   * 处理CAD文件
   * @param {File} file - CAD文件
   * @returns {Promise<Object>} 处理结果
   */
  async handleCADFile(file) {
    // 注意：CAD文件处理需要专门的库
    // 这里提供简化实现，实际项目中需要集成CAD处理库
    return new Promise((resolve, reject) => {
      // 简化处理：将CAD文件作为二进制数据读取
      const reader = new FileReader()
      
      reader.onload = (event) => {
        resolve({
          type: 'cad',
          data: event.target.result,
          fileName: file.name,
          fileSize: file.size,
          // 这里需要实际的CAD解析逻辑
          width: 1000, // 默认尺寸
          height: 800,
          aspectRatio: 1000 / 800
        })
      }
      
      reader.onerror = () => {
        reject(new Error('CAD文件读取失败'))
      }
      
      reader.readAsArrayBuffer(file)
    })
  }
  
  // ==================== 数据处理 ====================
  
  /**
   * 处理图纸数据
   * @param {Object} rawData - 原始数据
   * @param {File} file - 文件对象
   * @returns {Promise<Object>} 处理后的图纸数据
   */
  async processDrawingData(rawData, file) {
    const drawingData = {
      id: this.generateId(),
      name: file.name,
      type: rawData.type,
      file: file,
      rawData: rawData,
      layers: [],
      objects: [],
      metadata: {
        fileName: file.name,
        fileSize: file.size,
        fileType: file.type,
        importTime: new Date().toISOString(),
        width: rawData.width,
        height: rawData.height,
        aspectRatio: rawData.aspectRatio
      },
      bounds: {
        x: 0,
        y: 0,
        width: rawData.width,
        height: rawData.height
      }
    }
    
    // 根据文件类型创建相应的图层和对象
    if (rawData.type === 'image') {
      await this.processImageData(drawingData, rawData)
    } else if (rawData.type === 'pdf') {
      await this.processPDFData(drawingData, rawData)
    } else if (rawData.type === 'cad') {
      await this.processCADData(drawingData, rawData)
    }
    
    return drawingData
  }
  
  /**
   * 处理图片数据
   * @param {Object} drawingData - 图纸数据
   * @param {Object} rawData - 原始数据
   */
  async processImageData(drawingData, rawData) {
    // 创建图片图层
    const imageLayer = {
      id: this.generateId(),
      name: '导入图片',
      type: 'image',
      visible: true,
      locked: false,
      opacity: 1.0,
      objects: [{
        id: this.generateId(),
        type: 'image',
        x: 0,
        y: 0,
        width: rawData.width,
        height: rawData.height,
        imageData: rawData.data,
        image: rawData.image,
        visible: true,
        locked: false
      }]
    }
    
    drawingData.layers.push(imageLayer)
    drawingData.objects.push(...imageLayer.objects)
  }
  
  /**
   * 处理PDF数据
   * @param {Object} drawingData - 图纸数据
   * @param {Object} rawData - 原始数据
   */
  async processPDFData(drawingData, rawData) {
    // 创建PDF图层
    const pdfLayer = {
      id: this.generateId(),
      name: '导入PDF',
      type: 'pdf',
      visible: true,
      locked: false,
      opacity: 1.0,
      objects: [{
        id: this.generateId(),
        type: 'pdf',
        x: 0,
        y: 0,
        width: rawData.width,
        height: rawData.height,
        pdfData: rawData.data,
        pdf: rawData.pdf,
        page: rawData.page,
        visible: true,
        locked: false
      }]
    }
    
    drawingData.layers.push(pdfLayer)
    drawingData.objects.push(...pdfLayer.objects)
  }
  
  /**
   * 处理CAD数据
   * @param {Object} drawingData - 图纸数据
   * @param {Object} rawData - 原始数据
   */
  async processCADData(drawingData, rawData) {
    // 创建CAD图层
    const cadLayer = {
      id: this.generateId(),
      name: '导入CAD',
      type: 'cad',
      visible: true,
      locked: false,
      opacity: 1.0,
      objects: [{
        id: this.generateId(),
        type: 'cad',
        x: 0,
        y: 0,
        width: rawData.width,
        height: rawData.height,
        cadData: rawData.data,
        visible: true,
        locked: false
      }]
    }
    
    drawingData.layers.push(cadLayer)
    drawingData.objects.push(...cadLayer.objects)
  }
  
  // ==================== 工具方法 ====================
  
  /**
   * 生成唯一ID
   * @returns {string} 唯一ID
   */
  generateId() {
    return 'drawing_' + Date.now() + '_' + Math.random().toString(36).substr(2, 9)
  }
  
  /**
   * 获取导入状态
   * @returns {Object} 导入状态
   */
  getImportState() {
    return { ...this.importState }
  }
  
  /**
   * 获取图纸数据
   * @returns {Object} 图纸数据
   */
  getDrawingData() {
    return { ...this.drawingData }
  }
  
  /**
   * 清除图纸数据
   */
  clearDrawingData() {
    this.drawingData = {
      layers: [],
      objects: [],
      metadata: {},
      bounds: null
    }
  }
  
  /**
   * 重置导入状态
   */
  resetImportState() {
    this.importState = {
      isImporting: false,
      currentFile: null,
      progress: 0,
      error: null
    }
  }
}
